<template>
	<tm-drawer
		:disabbleScroll="true"
		:round="props.round"
		ref="drawer"
		:height="820"
		:closable="true"
		:overlayClick="aniover"
		@open="drawerOpen"
		@cancel="cancel"
		@ok="confirm"
		:show="showCity"
		@update:show="closeDrawer"
		title="请选择地区"
		ok-text="确认"
	>
		<tm-picker-view
			v-if="showCity"
            ref="picker"
			:height="590"
			@end="aniover = true"
			@start="aniover = false"
			:value="_colIndex"
			@update:modelValue="_colIndex = $event"
			@update:model-str="_colStr = $event"
			:model-str="_colStr"
			:default-value="_colIndex"
			:columns="_data"
		></tm-picker-view>
		<tm-button
			label="确认选择"
			block
			:margin="[32, 12]"
			:color="props.color"
			:linear="props.linear"
			:linear-deep="props.linearDeep"
			@click="confirm"
			:round="props.btnRound"
		></tm-button>
		<view :style="{ height: win_bottom + 'px' }"></view>
	</tm-drawer>
</template>
<script lang="ts" setup>
/**
 * 地区选择器
 * @description 这是弹出式，滑动地址选择器，另还一个按步选择地区的组件，见：tm-city-cascader
 * @example <tm-city-picker v-model:show="show" v-model="status" v-model:model-str="statusw"></tm-city-picker>
 */
import { PropType,inject, Ref, ref, watchEffect,getCurrentInstance,watch, toRaw, computed, nextTick, onMounted } from "vue"
import { custom_props } from "../../tool/lib/minxs";
import tmDrawer from '../tm-drawer/tm-drawer.vue';
import { childrenData } from "./interface"
import { provinceData } from "../../tool/static/province";
import { cityData } from "../../tool/static/city";
import { areaData } from "../../tool/static/area";
import tmPickerView from "../tm-picker-view/tm-picker-view.vue";
import TmSheet from "../tm-sheet/tm-sheet.vue";
import tmText from "../tm-text/tm-text.vue";
import tmButton from "../tm-button/tm-button.vue";
const proxy = getCurrentInstance()?.proxy??null;
const drawer = ref<InstanceType<typeof tmDrawer> | null>(null)
const picker = ref<InstanceType<typeof tmPickerView> | null>(null)
    
/**
 * 事件说明：
 * v-model:show 双向绑定显示和隐藏选择器
 * v-model 双向绑定以selectedModel为模式的值。一般用来给数据库后台用的。
 * v-model:model-str 单向输出地区名称，
 * 一般用来绑定在Input组件或者其它组件上用来展示当前选择的地址名称，
 * 但我们服务器可能有的是id或者index，所以你可以v-model绑定数据，用此v-model:model-str来显示数据。
 * confirm 点击了确认按钮时触发，返回当前选择数据。
 * cancel 取消或者点击遮罩关闭了选择器都将触发。
 */
const emits = defineEmits(["update:show", "update:modelValue", "update:modelStr", "confirm", "cancel"])
const props = defineProps({
    ...custom_props,
    followTheme: {
    	type: [Boolean,String],
    	default: true
    },
    //v-model以selectedModel为索引的值结果。
    modelValue: {
        type: Array as PropType<Array<string | number>>,
        default: () => []
    },
    //单向输出地区名称以/分割。不管selectedModel是以哪种索引选项，此处始终以地区名称输出显示。
    //可以使用v-model:modelStr，外部不可更改。
    modelStr: {
        type: String,
        default: ""
    },
    //v-model:show来双向绑定显示和隐藏选择器。
    show: {
        type: [Boolean],
        default: false
    },
    //赋值和选值方式
    //name:名称模式赋值和选择
    //id:地区id模式赋值和选择
    //index:索引模式赋值和选择
    selectedModel: {
        type: String,
        default: "id"
    },
	// 手动赋值城市数据
	city:{
		type:Array as PropType<Array<childrenData>>,
		default:()=>[]
	},
    color:{
        type:String,
        default:"primary"
    },
    linear:{
        type:String,
        default:""
    },
    linearDeep:{
        type:String,
        default:"light"
    },
    btnRound:{
        type:Number,
        default:3
    },
    round:{
        type:Number,
        default:12
    }
})
const showCity = ref(true)
const _cityData = computed(()=>props.city)
const _colIndex: Ref<Array<number>> = ref([])
const _data = ref(chiliFormatCity_area())
let tmid = NaN
const _colStr = ref('')
const aniover = ref(true)
const sysinfo = inject("tmuiSysInfo",{bottom:0,height:750,width:uni.upx2px(750),top:0,isCustomHeader:false,sysinfo:null})
let win_bottom = sysinfo.bottom

watchEffect(() => {
    showCity.value = props.show
})
watch([()=>props.city,()=>props.modelValue],()=>{
	_data.value = chiliFormatCity_area()
	clearTimeout(tmid)
	tmid =setTimeout(function() {
		getIndexBymodel(_data.value, props.selectedModel, 0, props.modelValue)
		defaultModerStrGet()
	}, 500);
},{deep:true})
function closeDrawer(e: boolean) {
    showCity.value = e;
    emits('update:show', showCity.value)
    getIndexBymodel(_data.value, "index", 0, toRaw(_colIndex.value))
	
}
// onMounted(()=>defaultModerStrGet())
function drawerOpen() {
	getIndexBymodel(_data.value, props.selectedModel, 0, props.modelValue)
}
//点击确认了地区。
function confirm() {
    if (!aniover.value) return
    setVal();
    nextTick(()=>{
        emits("confirm", props.modelValue)
        drawer.value?.close();
    })
}
function cancel() {
     if (!aniover.value) return
    emits('cancel')
}
function setVal() {
    let val = [];
    if (props.selectedModel == 'name') {
        val = _colStr.value.split("/") ?? [];
    } else if (props.selectedModel == 'id') {
        val = getRouterId(_data.value, 0)
    } else {
        val = [..._colIndex.value];
    }
	
    emits("update:modelValue", val)
    emits("update:modelStr", _colStr.value)
}
function defaultModerStrGet(){
	clearTimeout(tmid)
	tmid =setTimeout(function() {
		if(_colIndex.value.length>0){
			console.log(_colIndex.value,999)
		    let text = getRouterText(_data.value,0);
		    emits("update:modelStr",text.join("/"))
		}
	}, 200);
}
//模拟模型来返回index值
function getIndexBymodel(vdata:Array<childrenData> = [], model = "name", parentIndex = 0, value:Array<number|string> = []): Array<number|string> {
	if(value.length==0) return []
    if (model == 'name') {
        let item = vdata.filter(el => value[parentIndex] == el['text'])
        if (item.length == 0) {
            item = vdata[0];
            if (item) {
                value[parentIndex] = item['text'];
                _colIndex.value[parentIndex] = 0
                if (item['children']) {
                    getIndexBymodel(item['children'], model, parentIndex + 1, value);
                }
            }

        } else {
            item = item[0];
            if (item) {
                _colIndex.value[parentIndex] = vdata.findIndex(el => el['text'] == item['text'])
                if (item['children']) {
                    getIndexBymodel(item['children'], model, parentIndex + 1, value);
                }
            }
        }
    } else if (model == 'id') {
        let item = vdata.filter(el => value[parentIndex] == el['id'])
        if (item.length == 0) {
            item = vdata[0];
            if (item) {
                value[parentIndex] = item['id'];
                _colIndex.value[parentIndex] = 0
                if (item['children']) {
                    getIndexBymodel(item['children'], model, parentIndex + 1, value);
                }
            }

        } else {
            item = item[0];
            if (item) {
                _colIndex.value[parentIndex] = vdata.findIndex(el => el['id'] == item['id'])
                if (item['children']) {
                    getIndexBymodel(item['children'], model, parentIndex + 1, value);
                }
            }
        }
    }
	
    return _colIndex.value;
}
//返回 一个节点从父到子的路径id组。
function getRouterId(list:Array<childrenData>  = [], parentIndex = 0): Array<string | number> {
    let p: Array<string | number> = [];
    for (let i = 0; i < list.length; i++) {
        if (i == _colIndex.value[parentIndex]) {
            p.push(list[i]['id'])
            if (typeof _colIndex.value[parentIndex] != 'undefined') {
                let c = getRouterId(list[i]['children'], parentIndex + 1)
                p = [...p, ...c]
            }
            break;
        }
    }
    return p
}
//返回 一个节点从父到子的路径text组。
function getRouterText(list:Array<childrenData>  = [], parentIndex = 0): Array<string | number> {
    let p: Array<string | number> = [];
    for (let i = 0; i < list.length; i++) {
        if (i == _colIndex.value[parentIndex]) {
            p.push(list[i]['text'])
            if (typeof _colIndex.value[parentIndex] != 'undefined') {
                let c = getRouterText(list[i]['children'], parentIndex + 1)
                p = [...p, ...c]
            }
            break;
        }
    }
    return p
}
//格式化数据格式。
function chiliFormatCity_area() {
    let list: Array<childrenData> = [];
	
	if(_cityData.value.length>0){
		return _cityData.value
	}
	
    provinceData.forEach((item: childrenData, index: number) => {
        list.push({
            id: item.value??"",
            text: String(item.label),
            children: []
        })
    })
    if (props.cityLevel == 'province') return list;
    cityData.forEach((item: childrenData, index: number) => {
        item.forEach((citem: childrenData, cindex: number) => {
            list[index]?.children.push({
                id: citem.value??"",
                text: citem.label??"",
                children: []
            })
        })
    })
    if (props.cityLevel == 'city') return list;
    list.forEach((item, index) => {
        item.children.forEach((citem, cindex: number) => {
            areaData[index][cindex].forEach(jitem => {
                list[index]?.children[cindex]?.children.push({
                    id: jitem.value??"",
                    text: jitem.label??"",
                })
            })
        })
    })
    
	return list;
}
</script>
